﻿using System;
using System.IO;
using System.Text;
using System.Threading;

namespace FileStreamTest
{
    class Program
    {
        public class FileData
        {
            public FileStream stream;
            public int length;
            public byte[] byteData;
        }

        static void Main(string[] args)
        {
            ThreadPool.SetMaxThreads(1000, 1000);
            ThreadPoolMessage("Start");

            ReadFile();
            Console.WriteLine("after method ReadFile");


            Console.ReadKey();
        }

        //static void Callback(IAsyncResult result)
        //{
        //    Thread.Sleep(2000);
        //    ThreadPoolMessage("AsyncCallback");
        //    FileStream stream = (FileStream)result.AsyncState;
        //    stream.EndWrite(result);
        //    stream.Close();
        //}

        static void ReadFile()
        {
            byte[] byteData = new byte[80961024];
            FileStream stream = new FileStream("File1.sour", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite, 1024, true);

            FileData fileData = new FileData();
            fileData.stream = stream;
            fileData.length = (int)stream.Length;
            //Console.WriteLine("fileData.Length: " + fileData.length);
            fileData.byteData = byteData;

            stream.BeginRead(byteData, 0, fileData.length, new AsyncCallback(Completed), fileData);
        }

        static void Completed(IAsyncResult result)
        {
            ThreadPoolMessage("Completed");

            FileData fileData = (FileData)result.AsyncState;
            int length = fileData.stream.EndRead(result);
            fileData.stream.Close();

            if (length != fileData.length)
                throw new Exception("Stream is not complete!");

            string data = Encoding.ASCII.GetString(fileData.byteData, 0, fileData.length);
            Console.WriteLine(data.Substring(2, 22));
        }

        static void ThreadPoolMessage(string data)
        {
            int a, b;
            ThreadPool.GetAvailableThreads(out a, out b);
            string message = $"{data}\n CurrentThreadId is {Thread.CurrentThread.ManagedThreadId}\n " +
                $"WorkerThreads is:{a.ToString()} CompletionPortThreads is:{b.ToString()}";
            Console.WriteLine(message);
        }
    }
}
